#ifndef img_processer_h
#define img_processer_h
#include "image/img_processer.h"

void img_processer::showImage(const char *name, cv::Mat img, bool wait)
{
    cv::imshow(name, img);
    if (wait){
        cv::waitKey(0);
        cv::destroyAllWindows();
    }
}

img_processer::img_processer(const char *path) : imgPath(path)
{
}

img_processer::~img_processer()
{
}

void img_processer::process()
{
    cv::Mat image = cv::imread(this->imgPath); // 加载文件
   // showImage("oringin",image,false);

    cv::Mat target;
    cv::cvtColor(image,target,cv::COLOR_BGRA2GRAY); // 灰度化
    // cv::GaussianBlur(target,target,cv::Size(3,3),0);
    cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(2,cv::Size(10,10)); // 局部直方均衡化
   // cv::equalizeHist(target,target); // 全局直方均衡化
    clahe->apply(target,target);
    
    // target = target + 100;
    //     showImage("target4444",target, false);

    // cv::GaussianBlur(target,target,cv::Size(5,5),0); // 高斯去噪
    cv::Mat edged;
    cv::Canny(target,edged,120,200); // 查找符合条件的边缘
    std::vector<std::vector<cv::Point> > outRect;
    cv::findContours(edged,outRect,cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 查找外边缘

    std::vector<cv::Point> approxRect;
    std::vector<cv::Point> approxRectTmp;
    cv::Mat targetOringin;

    double maxArea = 0;
    for (size_t i = 0; i < outRect.size(); i++)
    {
       double epsilon = 0.01 * cv::arcLength(outRect[i],true); // 计算图形的周长
       
       cv::approxPolyDP(outRect[i],approxRectTmp,epsilon,true); // approxPolyDP

       double area = cv::contourArea(approxRectTmp);
       if (approxRectTmp.size() == 4 && area > maxArea){
            maxArea = area;
            approxRect = approxRectTmp;
       }
    }
   // showImage("edged",edged,false);
    cv::Mat outWarped;
    if (approxRect.size() == 4 && maxArea >  target.cols * target.rows * 0.4){
        // 计算最大矩形
        double widthA = std::sqrt(std::pow((approxRect[0].x - approxRect[3].x),2) + std::pow((approxRect[0].y - approxRect[3].y),2) );
        double widthB = std::sqrt(std::pow((approxRect[1].x - approxRect[2].x),2) + std::pow((approxRect[1].y - approxRect[2].y),2) );

        int maxwidth = std::max(widthA,widthB);

        double heightA = std::sqrt(std::pow((approxRect[0].x - approxRect[1].x),2) + std::pow((approxRect[0].y - approxRect[1].y),2) );
        double heightB = std::sqrt(std::pow((approxRect[2].x - approxRect[3].x),2) + std::pow((approxRect[2].y - approxRect[3].y),2) );

        int maxHeight = std::max(heightA,heightB);
        // 设置目标点
        std::vector<cv::Point2f> targetList(4);
        targetList[0] = cv::Point2f(0,0);
        targetList[1] = cv::Point2f(0,maxHeight);
        targetList[2] = cv::Point2f(maxwidth,maxHeight);
        targetList[3] = cv::Point2f(maxwidth,0);

        // std::vector<std::vector<cv::Point> > out3(1);
        // out3[0] = approxRect;
        // cv::drawContours(image, out3,-1,cv::Scalar(0,255,0),1);

        // int 转 double
        std::vector<cv::Point2f> outf(approxRect.size());
        for (size_t i = 0; i < approxRect.size(); i++)
        {
            outf[i] = cv::Point2f(approxRect[i].x,approxRect[i].y);
        }
    
        cv::Mat m = cv::getPerspectiveTransform(outf,targetList); // 获取变换矩阵
        cv::warpPerspective(target,outWarped,m,cv::Size(maxwidth,maxHeight)); // 透视变换
        cv::warpPerspective(image,targetOringin,m,cv::Size(maxwidth,maxHeight)); // 透视变换原图
        
    } else {
        outWarped = target;
        targetOringin = image;
    }


   // showImage("outWarped",outWarped, false);

    cv::Mat thresholdMat;
    cv::threshold(outWarped,thresholdMat,100,255,cv::THRESH_BINARY_INV|cv::THRESH_OTSU); // 二值化

    std::vector<std::vector<cv::Point> > targetRect;
    cv::findContours(thresholdMat,targetRect,cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 查找外边缘
    //showImage("thresholdMat",thresholdMat);
      //  showImage("thresholdMat",targetOringin);

    std::vector<std::vector<cv::Point> > targetRectTemp(1);
    double minArea = targetOringin.cols * targetOringin.rows * 0.005; // 筛选条件
    cv::Mat mask = cv::Mat::zeros(targetOringin.size(),CV_8UC1); // 创建一个全黑图片

    int max = 0;
    int step = 0;
    int index =  0;
    for (size_t i = 0; i < targetRect.size(); i++)
    {
        if (cv::contourArea(targetRect[i]) > minArea){
            targetRectTemp[0] = targetRect[i];
            cv::Mat maskImg; 
            mask.setTo(cv::Scalar(0,0,0));
            cv::drawContours(mask,targetRectTemp,-1,cv::Scalar(255,255,255),-1); // 绘制轮廓
           // showImage("thresholdMat",mask);
            cv::bitwise_and(thresholdMat,thresholdMat,maskImg,mask); // 获取轮廓
            // showImage("maskImg",maskImg);
            showImage("maskImg",maskImg);
            step++;
            int count = cv::countNonZero(maskImg); // 获取轮廓不为0的个数
            if (count > max){
                max = count;
                index =4 - ((step -1)% 5) ;
            }
            if (step % 5 == 0){
                printf("mask index = %c count = %d\n",'A' + index,max);
                max = 0; 
            }
        }
    }

    


}



#endif


